home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
BORL_TIP
/
TI100
/
TI1230.ASC
< prev
next >
Wrap
Text File
|
1993-01-25
|
14KB
|
529 lines
PRODUCT : Paradox Engine NUMBER : 1230
VERSION : 3.0
OS : DOS/WIN
DATE : January 25, 1993 PAGE : 1/8
TITLE : Workaround for PXSrchFld RecNotFound Problem
{
It has been brought to our attention that doing a PXSrchFld
with either the SEARCHFIRST or CLOSESTRECORD parameter will
fail in certain circumstances. Our QA department has an
example of this and is working on a solution.
We have created this workaround to use in the meantime. The
workaround is to do a CLOSESTRECORD search in place of the
SEARCHFIRST search. A CLOSESTRECORD search will leave the
record cursor on the first record that has a value greater than
the search value and return PXERR_RECNOTFOUND if an exact match
is not found. In some cases a CLOSESTRECORD search will treat
an exact match as the first value greater than the search value
(the problem that we are trying to get around).
What this workaround does is manually compare the search value
to the value in the current record when PXERR_RECNOTFOUND is
returned.
How to use this function:
=========================
Put this unit after the PXEngine unit in your USES clause.
This will cause the PXSrchFld in this unit to be called instead
of the original PXSrchFld in the PXEngine unit to be called.
You can define the variable DEBUG in order to determine when
you enter the special parts of the PXSrch function, using
either -DDEBUG at the command line while compiling, or under
'Options | Compiler | Conditional defines - in the IDE.
Using with the Database Framework ( DBF ):
==========================================
You will need to recompile the Database Framework with the
corrections to the USES clause ( see above ).
PRODUCT : Paradox Engine NUMBER : 1230
VERSION : 3.0
OS : DOS/WIN
DATE : January 25, 1993 PAGE : 2/8
TITLE : Workaround for PXSrchFld RecNotFound Problem
Differences between SrchFld.PXSrchFld and PXEngine.PXSrchFld:
1) SrchFld.PXSrchFld will move the current record cursor as
described for a CLOSESTRECORD search when doing a
SEARCHFIRST.
2) A number of different error messages could be returned
because of all the engine calls that occur in PXEngine.
PXSrchFld that would not be returned from
SrchFld.PXSrchFld.
3) A SEARCHFIRST can return PXERR_ENDOFTABLE in
SrchFld.PXSrch, which it would not in PXEngine.PXSrchFld.
The reason for this is to let you know when the record
cursor is at the end of the table, not at the first record
greater than the value that you are searching for. You
can change this behavior by searching for PXERR_ENDOFTABLE
and uncomment the
'SrchFld := PXERR_RECNOTFOUND ) ;
Exit;'
statements.
Limitations:
SrchFld.PXSrchFld will not work on composite or case
insensitive indexes, where it returns PXERR_INVFIELDHANDLE
(which can be at the beginning or SrchFld.PXSrchFld).
There is no way for us to determine which fields are part
of a composite secondary index (or of a case insensitive
index). What is needed is a routine similar to
SrchFld.PXSrchFld that knows which fields are part of
your secondary index and does the manual comparison on
those fields (on a case-insensitive index).
}
unit srchfld;
{$N+,E+}
interface
uses
PRODUCT : Paradox Engine NUMBER : 1230
VERSION : 3.0
OS : DOS/WIN
DATE : January 25, 1993 PAGE : 3/8
TITLE : Workaround for PXSrchFld RecNotFound Problem
{$ifdef Windows}
PXEngWin,
Strings;
{$else}
PxEngine;
{$endif}
function PXSrchFld(TblHandle : TableHandle;
RecHandle : RecordHandle;
FldHandle : FieldHandle;
Mode : integer) : integer;
implementation
const
SigFig = 0.00000000000001;
function PXSrchFld(TblHandle : TableHandle;
RecHandle : RecordHandle;
FldHandle : FieldHandle;
Mode : integer) : integer;
var
pxErr : integer;
RecHandleTemp : RecordHandle;
{$ifdef Windows}
FldType : array [0..6] of char;
{$else}
FldType : NameString;
{$endif}
StrFld1, StrFld2 : String;
CharFld1, CharFld2 : array [0..255] of char;
DateFld1, DateFld2 : TDate;
NumFld1, NumFld2 : Double;
ShortFld1, ShortFld2 : Integer;
begin
{ This function cannot handle composite/case-insensitive index}
if (FldHandle > 255) then begin
PXSrchFld := PXErr_InvFieldHandle;
PRODUCT : Paradox Engine NUMBER : 1230
VERSION : 3.0
OS : DOS/WIN
DATE : January 25, 1993 PAGE : 4/8
TITLE : Workaround for PXSrchFld RecNotFound Problem
exit;
end;
{$ifdef Windows}
pxErr := pxengwin.PXSrchFld(TblHandle, RecHandle,
FldHandle, Mode);
{$else}
pxErr := pxengine.PXSrchFld(TblHandle, RecHandle,
FldHandle, Mode);
{$endif}
case Mode of
SearchNext : begin
{ SearchNext Works }
PXSrchFld := pxErr;
Exit;
end;
SearchFirst, ClosestRecord : begin
{ Record found - everything OK }
if pxErr = pxSuccess then begin
PXSrchFld := pxErr;
exit;
end else
{ see if record really not there }
if pxErr = pxErr_RecNotFound then begin
{$ifdef debug}
writeln('Using special PXSrchFld operation');
{$endif}
{$ifdef Windows}
pxErr := PXFldType(TblHandle, FldHandle, 6, FldType);
{$else}
pxErr := PXFldType(TblHandle, FldHandle, FldType);
{$endif}
if pxErr <> PXSuccess then begin
PXSrchFld := pxErr;
exit;
end;
PRODUCT : Paradox Engine NUMBER : 1230
VERSION : 3.0
OS : DOS/WIN
DATE : January 25, 1993 PAGE : 5/8
TITLE : Workaround for PXSrchFld RecNotFound Problem
{ open a local temporary record buffer }
pxErr := PXRecBufOpen(TblHandle, RecHandleTemp);
if pxErr <> pxSuccess then begin
PXSrchFld := pxErr;
exit;
end;
{ Get the current rec and save to new record handle }
pxErr := PXRecGet(TblHandle, RecHandleTemp);
if pxErr <> pxSuccess then begin
PXRecBufClose(RecHandleTemp);
PXSrchFld := pxErr;
exit;
end;
{ do a manual comparison using the following steps: }
{ Get the value from the passed in record buffer }
case FldType[1] of
'A' : begin
{$ifDef Windows}
pxErr := PXGetAlpha(RecHandle, FldHandle,
256, CharFld1);
if pxErr = pxSuccess then begin
pxErr := PXGetAlpha(RecHandleTemp, FldHandle,
256, CharFld2);
if pxErr = pxSuccess then begin
{ close temp record buffer }
PXRecBufClose(RecHandleTemp);
if (StrComp(CharFld1, CharFld2) = 0) then
PXSrchFld := pxSuccess
else
PXSrchFld := pxErr_RecNotFound;
{$else}
pxErr := PXGetAlpha(RecHandle, FldHandle, StrFld1);
if pxErr = pxSuccess then begin
pxErr := PXGetAlpha(RecHandleTemp, FldHandle,
StrFld2);
if pxErr = pxSuccess then begin
{ close temp record buffer }
PXRecBufClose(RecHandleTemp);
PRODUCT : Paradox Engine NUMBER : 1230
VERSION : 3.0
OS : DOS/WIN
DATE : January 25, 1993 PAGE : 6/8
TITLE : Workaround for PXSrchFld RecNotFound Problem
if StrFld1 = StrFld2 then
PXSrchFld := pxSuccess
else
PXSrchFld := pxErr_RecNotFound;
{$endif}
exit;
end;
end;
end;
'D' : begin
pxErr := PXGetDate(RecHandle, FldHandle, DateFld1);
if pxErr = pxSuccess then begin
pxErr := PXGetDate(RecHandleTemp, FldHandle,
DateFld2);
if pxErr = pxSuccess then begin
{ close temp record buffer }
PXRecBufClose(RecHandleTemp);
if DateFld1 = DateFld2 then
PXSrchFld := pxSuccess
else
PXSrchFld := pxErr_RecNotFound;
exit;
end;
end;
end;
'N' : begin
pxErr := PXGetDoub(RecHandle, FldHandle, NumFld1);
if pxErr = pxSuccess then begin
pxErr := PXGetDoub(RecHandleTemp, FldHandle,
NumFld2);
if pxErr = pxSuccess then begin
{ close temp record buffer }
PXRecBufClose(RecHandleTemp);
{ Test if either value was blank }
{ If both are blank then treat as not equal }
if (NumFld1 = 0) <> (NumFld2 = 0) then begin
PRODUCT : Paradox Engine NUMBER : 1230
VERSION : 3.0
OS : DOS/WIN
DATE : January 25, 1993 PAGE : 7/8
TITLE : Workaround for PXSrchFld RecNotFound Problem
PXSrchFld := pxErr_RecNotFound;
Exit;
end;
{ We use this method for comparing floating }
{ point numbers because of the way floats are }
{ represented in binary. Example, we cannot }
{ guarantee if (.100 - .23) = .67 is going to }
{ return true because .23 might be .229998 as }
{ represented internally. }
if NumFld1 <> NumFld2 then
PXSrchFld := pxSuccess
else
PXSrchFld := pxErr_RecNotFound;
exit;
NumFld1 := Abs(NumFld1 - NumFld2);
if NumFld1 < SigFig then
PXSrchFld := pxSuccess
else
PXSrchFld := pxErr_RecNotFound;
end;
end;
end;
'S' : begin
pxErr := PXGetShort(RecHandle, FldHandle,
ShortFld1);
if pxErr = pxSuccess then begin
pxErr := PXGetShort(RecHandleTemp, FldHandle,
ShortFld2);
if pxErr = pxSuccess then begin
{ close temp record buffer }
PXRecBufClose(RecHandleTemp);
if ShortFld1 = ShortFld2 then
PXSrchFld := pxSuccess
else
PRODUCT : Paradox Engine NUMBER : 1230
VERSION : 3.0
OS : DOS/WIN
DATE : January 25, 1993 PAGE : 8/8
TITLE : Workaround for PXSrchFld RecNotFound Problem
PXSrchFld := pxErr_RecNotFound;
exit;
end;
end;
end;
end;
end;
if pxErr = pxErr_EndOfTable then
if Mode = SearchFirst then begin
{ Uncomment out the next line of you want }
{ pxErr_RecNotFound returned by SearchFirst if the }
{ cursor is left at the end of the table (PXSrchFld }
{ with the SearchFirst parameter will not return }
{ pxErr_EndOfTable). }
{
PXSrchFld := pxErr_RecNotFound;
Exit;
}
end
else begin
PXSrchFld := pxErr;
Exit;
end;
end;
end;
PXSrchFld := pxErr;
end;
end.
DISCLAIMER: You have the right to use this technical information
subject to the terms of the No-Nonsense License Statement that
you received with the Borland product to which this information
pertains.